home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 …ember: Reference Library / Dev.CD Dec 00 RL Disk 1.toast / pc / technical documentation / develop / develop issue 26 / develop issue 26 code / som and listpart / listpart dr4 / source / listpartutils.cpp < prev    next >
Encoding:
Text File  |  1995-12-03  |  21.5 KB  |  780 lines

  1. /*
  2.     File:        ListPartUtils.cpp
  3.  
  4.     Contains:    ListPart utility functions & classes
  5.  
  6.     Written by:    Steve Smith
  7.  
  8.     Copyright:    © 1994,95 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- OpenDoc Utilities --
  18.  
  19. #ifndef _EXCEPT_
  20. // Exceptions define several important macros (ie. CHECKENV)
  21. // which are used in the SOM method dispatch glue. If Except.h
  22. // is not included early enough, exceptions may not be thrown
  23. // correctly when returning from a SOM method with the "ev" parameter set.
  24. #include <Except.h>
  25. #endif
  26.  
  27. // --- ListPart Includes ---
  28.  
  29. #ifndef _LISTPARTUTILS_
  30. #include "ListPartUtils.h"
  31. #endif
  32.  
  33. #ifndef _LISTPARTDEF_
  34. #include "ListPartDef.h"
  35. #endif
  36.  
  37. // --- OpenDoc Includes ---
  38.  
  39. #ifndef _ODTYPES_
  40. #include <ODTypes.h>
  41. #endif
  42.  
  43. #ifndef SOM_Module_OpenDoc_StdProps_defined
  44. #include <StdProps.xh>
  45. #endif
  46.  
  47. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  48. #include <StdTypes.xh>
  49. #endif
  50.  
  51. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  52. #include <StdDefs.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODFrame_xh
  56. #include <Frame.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODSession_xh
  60. #include <ODSessn.xh>
  61. #endif
  62.  
  63. #ifndef SOM_ODDraft_xh
  64. #include <Draft.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODStorageUnit_xh
  68. #include <StorageU.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODStorageUnitView_xh
  72. #include <SUView.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODDocument_xh
  76. #include <Document.xh>
  77. #endif
  78.  
  79. #ifndef SOM_ODContainer_xh
  80. #include <ODCtr.xh>
  81. #endif
  82.  
  83. #ifndef SOM_ODNameSpaceManager_xh
  84. #include <NmSpcMg.xh>
  85. #endif
  86.  
  87. #ifndef SOM_ODValueNameSpace_xh
  88. #include <ValueNS.xh>
  89. #endif
  90.  
  91. #ifndef SOM_ODWindowState_xh
  92. #include <WinStat.xh>
  93. #endif
  94.  
  95. // -- OpenDoc Utilities --
  96.  
  97. #ifndef _BNDNSUTL_
  98. #include <BndNSUtl.h>
  99. #endif
  100.  
  101. #ifndef _DOCUTILS_
  102. #include <DocUtils.h>
  103. #endif
  104.  
  105. #ifndef _ISOSTR_
  106. #include <ISOStr.h>
  107. #endif
  108.  
  109. #ifndef _ODDEBUG_
  110. #include <ODDebug.h>
  111. #endif
  112.  
  113. #ifndef _STDTYPIO_
  114. #include <StdTypIO.h>
  115. #endif
  116.  
  117. #ifndef _STORUTIL_    
  118. #include <StorUtil.h>
  119. #endif
  120.  
  121. #ifndef _TEMPOBJ_
  122. #include <TempObj.h>
  123. #endif
  124.  
  125. #ifndef _TEMPITER_
  126. #include <TempIter.h>
  127. #endif
  128.  
  129. #ifndef _USERSRCM_
  130. #include <UseRsrcM.h>
  131. #endif
  132.  
  133. // --- Macintosh Includes ---
  134.  
  135. #ifndef __RESOURCES__
  136. #include <Resources.h>
  137. #endif
  138.  
  139. #ifndef __GXMATH__
  140. #include <GXMath.h>
  141. #endif
  142.  
  143. #ifndef __SCRIPT__
  144. #include <Script.h>
  145. #endif
  146.  
  147. #ifndef __TEXTUTILS__
  148. #include <TextUtils.h>
  149. #endif
  150.  
  151.  
  152. #pragma segment ListPartUtilities
  153.  
  154.  
  155. //====================================================================
  156. // Utility Functions
  157. //====================================================================
  158.  
  159. //--------------------------------------------------------------------
  160. // GetPartName
  161. //--------------------------------------------------------------------
  162.  
  163. ODIText* GetPartName(Environment* ev, ODPart* part, ODType category)
  164. {
  165.     ASSERT(part != kODNULL, kODErrIllegalNullPartInput);
  166.  
  167.     // Get the root part of the document.
  168.     ODDraft* draft = ODGetDraft(ev,part);
  169.     TempODPart rootPart = ODAcquireRootPartOfDraft(ev, draft);
  170.     
  171.     // Get the part name.
  172.     // If we can't get a valid name for the part, we generate one using
  173.     // the user visible category name of the part's category.
  174.     TempODIText partName = ODGetITextProp(ev, part->GetStorageUnit(ev), 
  175.                                          kODPropName, kODMacIText, kODNULL);
  176.     
  177.     // If the part is the root of the document, return the name of the file.
  178.     if ( ODObjectsAreEqual(ev, part, rootPart) )
  179.     {
  180.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);
  181.         TempPlatformFile file = GetPlatformFileFromContainer(ev, container);
  182.  
  183.         TempODIText fileName = file->GetName();
  184.         
  185.         // Test the file name against the part name. If the two are equivalent
  186.         // (not equal), then use the part name.
  187.         if ( !NamesAreEquivalent(ev, fileName, partName) )
  188.         {
  189.             // If the names are different, return the file name.
  190.             // (This code transfers the ODIText object to the partName tempobj)
  191.             DisposeIText(partName.DontDelete());
  192.             partName = fileName.DontDelete();
  193.         }
  194.     }
  195.     else
  196.     {
  197.         if ( (partName == kODNULL) || (GetITextStringLength(partName) == 0) )
  198.         {
  199.             ODIText* categoryName;
  200.             ODNameSpaceManager* nsMgr = ODGetSession(ev,part)->GetNameSpaceManager(ev);
  201.             
  202.             // Get the category string from the category name space.
  203.             if ( GetUserCatFromCat(nsMgr, category, &categoryName) )
  204.             {
  205.                 // If we successfully retrieved the category user string, return it.
  206.                 // (This code transfers the ODIText object to the partName tempobj)
  207.                 DisposeIText(partName.DontDelete());
  208.                 partName = categoryName;
  209.             }
  210.             else
  211.             {
  212.     #if ODDebug
  213.                 // This should never happen. Check NMAP for errors.
  214.                 DebugStr("\pCategory NMAP bad, or Preferences corrupted.");
  215.     #else
  216.                 THROW(kODErrInvalidNSType);
  217.     #endif
  218.             }
  219.         }
  220.     }
  221.     
  222.     return partName.DontDelete();
  223. }
  224.  
  225. //--------------------------------------------------------------------
  226. // NamesAreEquivalent
  227. //--------------------------------------------------------------------
  228.  
  229. ODBoolean NamesAreEquivalent(Environment* ev, ODIText* fileName,
  230.                                         ODIText* partName)
  231. {
  232.     Str255 fileStr;
  233.     Str255 partStr;
  234.     
  235.     // If the strings are in different languages, we're done.
  236.     if ( (GetITextScriptCode(fileName) != GetITextScriptCode(partName)) ||
  237.             GetITextLangCode(fileName) != GetITextLangCode(partName) )
  238.         return kODFalse;
  239.     
  240.     GetITextPString(fileName, fileStr);
  241.     GetITextPString(partName, partStr);
  242.  
  243.     // If the string lengths are different, we're done.
  244.     if ( fileStr[0] != partStr[0] )
  245.         return kODFalse;
  246.  
  247.     // Return the Toolbox string equivalence test.
  248.     return EqualString(fileStr,partStr,kODTrue,kODTrue);
  249. }
  250.  
  251. //--------------------------------------------------------------------
  252. // GetEditorScriptLanguage
  253. //--------------------------------------------------------------------
  254.  
  255. void GetEditorScriptLanguage(Environment* ev, ACF_DevServ_som_ListPart* fsomSelf, ODScriptCode* script,
  256.                                         ODLangCode* language)
  257. {
  258.     long region;
  259.     
  260.     ODSLong rfRef;
  261.     rfRef = fsomSelf->OverrideBeginUsingLibraryResources(ev);
  262.     {
  263.         Handle versHdl = Get1Resource('vers', 1);
  264.         
  265.         // Get the region code of the editor, otherwise use the
  266.         // region code the of the primary system script.
  267.         
  268.         if ( versHdl )
  269.         {
  270.             region = (long)(*(VersRecHndl)versHdl)->countryCode;
  271.             ReleaseResource(versHdl);
  272.         }
  273.         else
  274.         {
  275.             region = GetScriptManagerVariable(smRegionCode);
  276.         }
  277.         
  278.         // Spanish & Japanese are not actually supported by the editor.
  279.         // They are provided as examples of how to add recognition of
  280.         // additional regions (see Script.h for region codes).
  281.         
  282.         switch ((short)region) {
  283.             case verUS:
  284.                 *script = smRoman;
  285.                 *language = langEnglish;
  286.                 break;
  287.             case verSpain:
  288.                 *script = smRoman;
  289.                 *language = langSpanish;
  290.                 break;
  291.             case verJapan:
  292.                 *script = smJapanese;
  293.                 *language = langJapanese;
  294.                 break;
  295.             default:
  296.                 *script = smRoman;
  297.                 *language = langEnglish;
  298.         }                
  299.     }
  300.     fsomSelf->OverrideEndUsingLibraryResources(ev, rfRef);
  301. }
  302.  
  303. //--------------------------------------------------------------------
  304. // FixedToIntRect
  305. //--------------------------------------------------------------------
  306.  
  307. void FixedToIntRect(ODRect& fixedRect, Rect& intRect)
  308. {
  309.     intRect.top        = FixedToInt(fixedRect.top);
  310.     intRect.left    = FixedToInt(fixedRect.left);
  311.     intRect.bottom    = FixedToInt(fixedRect.bottom);
  312.     intRect.right    = FixedToInt(fixedRect.right);
  313. }
  314.  
  315. //--------------------------------------------------------------------
  316. // IntToFixedRect
  317. //--------------------------------------------------------------------
  318.  
  319. void IntToFixedRect(Rect& intRect, ODRect& fixedRect)
  320. {
  321.     fixedRect.left        = ff(intRect.left);
  322.     fixedRect.top        = ff(intRect.top);
  323.     fixedRect.right        = ff(intRect.right);
  324.     fixedRect.bottom    = ff(intRect.bottom);
  325. }
  326.  
  327. //--------------------------------------------------------------------
  328. // LoadThumbnail
  329. //--------------------------------------------------------------------
  330.  
  331. void LoadThumbnail(Environment* ev, ACF_DevServ_som_ListPart* fsomSelf, Handle* thumbnail)
  332. {
  333.     if ( *thumbnail ) return;
  334.     
  335.     ODSLong rfRef;
  336.     rfRef = fsomSelf->OverrideBeginUsingLibraryResources(ev);
  337.     {
  338.         *thumbnail = (Handle) GetPicture(kThumbnailPicture);
  339.     }
  340.     fsomSelf->OverrideEndUsingLibraryResources(ev, rfRef);
  341. }
  342.  
  343. //--------------------------------------------------------------------
  344. // TilePartWindow
  345. //--------------------------------------------------------------------
  346.  
  347. Rect TilePartWindow(Environment* ev, Rect* facetBounds, Rect* partWindowBounds)
  348. {
  349.     const short    kWindowTilingConst    = 20;
  350.     const short kLeftToRight        = 0;
  351.     const short kRightToLeft        = -1;
  352.     
  353.     short direction;
  354.     
  355.     // Get the direction for the primary script system running on this machine.
  356.     // (Right-to-Left or Left-to-Right)
  357.     direction = GetSysDirection();
  358.     
  359.     // The child window should be tiled from the topLeft corner of the 
  360.     // active facet whose frame is being opened.
  361.     if ( direction == kLeftToRight )
  362.     {
  363.         // Position the window rect at the top/left corner of the facet.
  364.         OffsetRect(partWindowBounds, facetBounds->left, facetBounds->top);
  365.         // Now tile the window rect down and to the right.
  366.         OffsetRect(partWindowBounds, kWindowTilingConst, kWindowTilingConst);
  367.     }
  368.     // The child window should be tiled from the topRight corner of the 
  369.     // active facet whose frame is being opened.
  370.     else if ( direction == kRightToLeft )
  371.     {
  372.         // Position the window rect at the top/right corner of the facet.
  373.         OffsetRect(partWindowBounds, (partWindowBounds->right - facetBounds->right),
  374.                     facetBounds->top);
  375.         // Now tile the window rect down and to the left.
  376.         OffsetRect(partWindowBounds, -kWindowTilingConst, kWindowTilingConst);
  377.     }
  378.     
  379.     return *partWindowBounds;
  380. }
  381.  
  382. //--------------------------------------------------------------------
  383. // CountFacets
  384. //--------------------------------------------------------------------
  385.  
  386. ODUShort CountFramesFacets(Environment* ev, ODFrame* frame)
  387. {
  388.     ODUShort facetCount = 0;
  389.     ODFacet* facet;
  390.     
  391.     TempODFrameFacetIterator ffiter(ev, frame);
  392.     facet = ffiter.First();
  393.     while ( ffiter.IsNotComplete() )
  394.     {
  395.         facetCount++;
  396.         facet = ffiter.Next();
  397.     }
  398.     
  399.     return facetCount;
  400. }
  401.  
  402. //=========================================================================
  403. // CFrameProxy
  404. //=========================================================================
  405.  
  406. //-------------------------------------------------------------------------
  407. // CFrameProxy::SetFrame
  408. //
  409. // The code will not affect the proxy fields unless it can
  410. // successfully acquire the incoming frame, its id, and
  411. // the draft the frame lives in. If something goes wrong,
  412. // the proxy remains unchanged.
  413. //-------------------------------------------------------------------------
  414.  
  415. void CFrameProxy::SetFrame(Environment* ev, ODFrame* frame)
  416. {
  417.     ASSERT(frame!=kODNULL, kODErrIllegalNullFrameInput);
  418.     
  419.     ODID id;
  420.     ODDraft* draft;
  421.     
  422.     // Using the temp object will cleanup the incoming
  423.     // frame's refcount if something goes wrong.
  424.     frame->Acquire(ev);
  425.     TempODFrame tFrame = frame;
  426.     
  427.     // Perform all the operations that can fail, first.
  428.     TempODPart tPart = frame->AcquirePart(ev);
  429.     id = frame->GetID(ev);
  430.     draft = ODGetDraft(ev, tPart);
  431.     ODReleaseObject(ev, fFrame);
  432.  
  433.     // If all went well, set the proxy fields.
  434.     fFrame = tFrame.DontRelease();
  435.     fID = id;
  436.     fDraft = draft;
  437. }
  438.  
  439. //-------------------------------------------------------------------------
  440. // CFrameProxy::GetFrame
  441. //-------------------------------------------------------------------------
  442.  
  443. ODFrame* CFrameProxy::GetFrame(Environment* ev)
  444. {
  445.     if ( fFrame == kODNULL )
  446.     {
  447.         TRY
  448.             TempODFrame frame = fDraft->AcquireFrame(ev, fID);
  449.             this->SetFrame(ev,frame);
  450.         CATCH_ALL
  451.             fFrame = kODNULL;
  452.             fID = kODNULLID;
  453.         ENDTRY
  454.     }
  455.     return fFrame;
  456. }
  457.  
  458. //-------------------------------------------------------------------------
  459. // CFrameProxy::Purge
  460. //-------------------------------------------------------------------------
  461.  
  462. void CFrameProxy::Purge(Environment* ev)
  463. {
  464.     if ( this->FrameIsLoaded() )
  465.     {
  466.         fID = fFrame->GetID(ev);
  467.         ODReleaseObject(ev, fFrame);
  468.     }
  469. }
  470.  
  471. //=========================================================================
  472. // CFrameInfo
  473. //=========================================================================
  474.  
  475. //-------------------------------------------------------------------------
  476. // CFrameInfo::CFrameInfo
  477. //-------------------------------------------------------------------------
  478.  
  479. CFrameInfo::CFrameInfo(ODSession* session)
  480. {
  481.     fSession = session;
  482.     fFrameActive = kODFalse;
  483.     fFrameReactivate  = kODFalse;
  484.     fShouldDisposeWindow = kODFalse;
  485.     fActiveFacet = kODNULL;
  486.     fSourceFrame = kODNULL;
  487.     fDependentFrame = kODNULL;
  488.     fPartWindowID = kODNULLID; 
  489. }
  490.  
  491. //-------------------------------------------------------------------------
  492. // CFrameInfo::~CFrameInfo
  493. //-------------------------------------------------------------------------
  494.  
  495. CFrameInfo::~CFrameInfo()
  496. {
  497.     // Deleting the proxies will release the encapsulated frames.
  498.     ODDeleteObject(fDependentFrame);
  499.     ODDeleteObject(fSourceFrame);
  500. }
  501.  
  502. //-------------------------------------------------------------------------
  503. // CFrameInfo::Externalize
  504. //-------------------------------------------------------------------------
  505.  
  506. void CFrameInfo::Externalize(Environment* ev, ODStorageUnitView* storageUnitView)
  507. {
  508.     // This method assumes that OpenDoc has passed us a storageUnitView
  509.     // that is focused to a property, but no particular value.
  510.     
  511.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  512.  
  513.     this->CleanseFrameInfoProperty(ev, storageUnit);
  514.     this->ExternalizeFrameInfo(ev, storageUnit, kODNULLKey, kODNULL);
  515. }
  516.  
  517. //-------------------------------------------------------------------------
  518. // CFrameInfo::CleanseFrameInfoProperty
  519. //-------------------------------------------------------------------------
  520.  
  521. void CFrameInfo::CleanseFrameInfoProperty(Environment* ev, ODStorageUnit* storageUnit)
  522. {
  523.     ODULong numValues;
  524.     ODULong index;
  525.         
  526.     numValues = storageUnit->CountValues(ev);
  527.     
  528.     for (index = numValues; index >= 1; index--)
  529.     {
  530.         // Index, from 1 to n, through the values.
  531.         storageUnit->Focus(ev, kODNULL, kODPosSame, 
  532.                                 kODNULL, index, kODPosUndefined);
  533.                                 
  534.         // Get the ISO type name for the value. The temp object
  535.         // will automatically delete the returned value when this
  536.         // scope is exited.
  537.         TempODValueType value = storageUnit->GetType(ev);
  538.         
  539.         // If the value type is not one we support, remove it.
  540.         if ( ODISOStrCompare(value, kListPartInfo) != 0 )
  541.             storageUnit->Remove(ev);
  542.     }
  543. }
  544.  
  545. //-------------------------------------------------------------------------
  546. // CFrameInfo::ExternalizeFrameInfo
  547. //-------------------------------------------------------------------------
  548.  
  549. void CFrameInfo::ExternalizeFrameInfo(Environment* ev, ODStorageUnit* storageUnit,
  550.                                         ODDraftKey key, ODFrame* scopeFrame)
  551. {
  552.     // This method behaves much the same way as the ListPart::ExternalizeStateInfo
  553.     // method.
  554.     
  555.     if ( storageUnit->Exists(ev, kODNULL, kListPartInfo, 0) )
  556.     {
  557.         // Persistent object references are stored in a side table, rather than
  558.         // in the property/value stream. Thus, deleting the contents of a value
  559.         // will not "delete" the references previously written to that value. To
  560.         // completely "delete" all references written to the value, we must
  561.         // remove the value and add it back.
  562.  
  563.         storageUnit->Focus(ev, kODNULL, kODPosSame, kListPartInfo, 0, kODPosUndefined);
  564.         storageUnit->Remove(ev);
  565.     }
  566.  
  567.     // Add a value to write the data into.
  568.     storageUnit->AddValue(ev, kListPartInfo);
  569.     
  570.     // Write a weak reference to our source frame.
  571.     {
  572.         ODStorageUnitRef weakRef = {0,0,0,0};
  573.         
  574.         if ( fSourceFrame )
  575.         {
  576.             ODID        frameID = fSourceFrame->GetID();
  577.             ODID        scopeFrameID = ( scopeFrame ? scopeFrame->GetID(ev) : kODNULLID );
  578.             ODDraft*    fromDraft = fSourceFrame->GetDraft();
  579.     
  580.             // If a draft key exists, then we are being cloned to another draft.
  581.             // We must "weak" clone our display frame and reference the cloned
  582.             // frame. The part re-uses the frameID variable so there aren't two
  583.             // different GetWeakStorageUnitRef calls.
  584.             if ( key )
  585.                 frameID = fromDraft->WeakClone(ev, key, frameID, kODNULLID, scopeFrameID);
  586.             
  587.             // Write out weak references to each of the part's display frames.
  588.             storageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  589.         }
  590.         StorageUnitSetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  591.     }
  592.     
  593.     // Write a weak reference to our dependent frame.
  594.     {
  595.         ODStorageUnitRef weakRef = {0,0,0,0};
  596.         
  597.         if ( fDependentFrame )
  598.         {
  599.             ODID        frameID = fDependentFrame->GetID();
  600.             ODID        scopeFrameID = ( scopeFrame ? scopeFrame->GetID(ev) : kODNULLID );
  601.             ODDraft*    fromDraft = fDependentFrame->GetDraft();
  602.     
  603.             // If a draft key exists, then we are being cloned to another draft.
  604.             // We must "weak" clone our display frame and reference the cloned
  605.             // frame. The part re-uses the frameID variable so there aren't two
  606.             // different GetWeakStorageUnitRef calls.
  607.             if ( key )
  608.                 frameID = fromDraft->WeakClone(ev, key, frameID, kODNULLID, scopeFrameID);
  609.             
  610.             // Write out weak references to each of the part's display frames.
  611.             storageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  612.         }
  613.         StorageUnitSetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  614.     }
  615. }
  616.  
  617. //-------------------------------------------------------------------------
  618. // CFrameInfo::CloneInto
  619. //-------------------------------------------------------------------------
  620.  
  621. void CFrameInfo::CloneInto(Environment *ev, ODDraftKey key,
  622.                             ODStorageUnitView* storageUnitView, ODFrame* scopeFrame)
  623. {
  624.     // This method assumes that OpenDoc has passed us a storageUnitView
  625.     // that is focused to a property, but no particular value.
  626.     
  627.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  628.  
  629.     if ( storageUnit->Exists(ev, kODNULL, kListPartInfo, 0) == kODFalse )
  630.     {
  631.         this->ExternalizeFrameInfo(ev, storageUnit, key, scopeFrame);
  632.     }
  633. }
  634.  
  635. //-------------------------------------------------------------------------
  636. // CFrameInfo::InitFromStorage
  637. //------------------------------------------------------------------------------
  638.  
  639. void CFrameInfo::InitFromStorage(Environment* ev, ODStorageUnitView* storageUnitView)
  640. {
  641.     // This method assumes that OpenDoc has passed us a storageUnitView
  642.     // that is focused to a property, but no particular value.
  643.     
  644.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  645.  
  646.     if ( storageUnit->Exists(ev, kODNULL, kListPartInfo, 0) )
  647.     {
  648.         TRY
  649.             storageUnit->Focus(ev, kODNULL, kODPosSame,
  650.                                         kListPartInfo, 0 , kODPosUndefined);
  651.     
  652.             ODStorageUnitRef weakRef = {0,0,0,0};
  653.             StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef),
  654.                                 (ODPtr)&weakRef);
  655.             
  656.             if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  657.             {
  658.                 // Convert the reference into a runtime id.
  659.                 ODID frameID = storageUnit->GetIDFromStorageUnitRef(ev, weakRef);
  660.  
  661.                 // Create a proxy class to support the lazy internalization.
  662.                 CFrameProxy* proxy = new CFrameProxy;
  663.                 proxy->InitFrameProxy(frameID, ODGetDraft(ev,storageUnit));
  664.  
  665.                 // Store the proxy source frame.
  666.                 fSourceFrame = proxy;
  667.             }
  668.             
  669.         CATCH_ALL
  670.             ODDeleteObject(fSourceFrame);
  671.             fSourceFrame = kODNULL;
  672.         ENDTRY
  673.  
  674.         TRY
  675.             ODStorageUnitRef weakRef = {0,0,0,0};
  676.             StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef),
  677.                                 (ODPtr)&weakRef);
  678.             
  679.             if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  680.             {
  681.                 // Convert the reference into a runtime id.
  682.                 ODID frameID = storageUnit->GetIDFromStorageUnitRef(ev, weakRef);
  683.  
  684.                 // Create a proxy class to support the lazy internalization.
  685.                 CFrameProxy* proxy = new CFrameProxy;
  686.                 proxy->InitFrameProxy(frameID, ODGetDraft(ev,storageUnit));
  687.  
  688.                 // Store the proxy dependent frame.
  689.                 fDependentFrame = proxy;
  690.             }
  691.             
  692.         CATCH_ALL
  693.             ODDeleteObject(fDependentFrame);
  694.             fDependentFrame = kODNULL;
  695.         ENDTRY
  696.     }
  697. }
  698.  
  699. //-------------------------------------------------------------------------
  700. // CFrameInfo::SetSourceFrame
  701. //-------------------------------------------------------------------------
  702.  
  703. void CFrameInfo::SetSourceFrame(Environment* ev, ODFrame* frame)
  704. {
  705.     if ( frame != kODNULL )
  706.     {
  707.         // Create a proxy class to support the lazy internalization.
  708.         CFrameProxy* proxy = new CFrameProxy;
  709.         proxy->InitFrameProxy(ev,frame);
  710.         
  711.         // Store the proxy source frame after clearing the old one.
  712.         ODDeleteObject(fSourceFrame);
  713.         fSourceFrame = proxy;
  714.     }
  715. }
  716.  
  717. //-------------------------------------------------------------------------
  718. // CFrameInfo::ReleaseSourceFrame
  719. //-------------------------------------------------------------------------
  720.  
  721. void CFrameInfo::ReleaseSourceFrame(Environment* ev)
  722. {
  723.     ODDeleteObject(fSourceFrame);
  724. }
  725.  
  726. //-------------------------------------------------------------------------
  727. // CFrameInfo::SetDependentFrame
  728. //-------------------------------------------------------------------------
  729.  
  730. void CFrameInfo::SetDependentFrame(Environment* ev, ODFrame* frame)
  731. {
  732.     if ( frame != kODNULL )
  733.     {
  734.         // Create a proxy class to support the lazy internalization.
  735.         CFrameProxy* proxy = new CFrameProxy;
  736.         proxy->InitFrameProxy(ev,frame);
  737.         
  738.         // Store the proxy dependent frame after clearing the old one.
  739.         ODDeleteObject(fDependentFrame);
  740.         fDependentFrame = proxy;
  741.     }
  742. }
  743.  
  744. //-------------------------------------------------------------------------
  745. // CFrameInfo::ReleaseDependentFrame
  746. //-------------------------------------------------------------------------
  747.  
  748. void CFrameInfo::ReleaseDependentFrame(Environment* ev)
  749. {
  750.     ODDeleteObject(fDependentFrame);
  751. }
  752.  
  753. //-------------------------------------------------------------------------
  754. // CFrameInfo::GetPartWindow
  755. //-------------------------------------------------------------------------
  756.  
  757. ODWindow* CFrameInfo::AcquirePartWindow(Environment* ev)
  758. {
  759.     ODWindow* window = kODNULL;
  760.     
  761.     if ( fPartWindowID )
  762.     {
  763.         window = fSession->GetWindowState(ev)->AcquireWindow(ev,fPartWindowID);
  764.         if ( !window) fPartWindowID = kODNULLID;
  765.     }
  766.     
  767.     return window;
  768. }
  769.  
  770. //-------------------------------------------------------------------------
  771. // CFrameInfo::SetPartWindow
  772. //-------------------------------------------------------------------------
  773.  
  774. void CFrameInfo::SetPartWindow(Environment* ev, ODWindow* window)
  775. {
  776.     fPartWindowID = window ? window->GetID(ev) : kODNULLID;
  777. }
  778.  
  779.  
  780.